using AutoMapper;
using Domain;
using ErrorCode;
using Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using RabbitTraceability.Api.Applications.Command;
using RabbitTraceability.Api.Dtos.Response;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace RabbitTraceability.Api.Applications.CommandHandler
{
    /// <summary>
    /// 查询养殖信息命令处理程序
    /// </summary>
    public class QueryBreedingInfoCommandHandler : IRequestHandler<QueryBreedingInfoCommand, BreedingInfoResponseDto>
    {
        private readonly IRepository<BreedingInfo> _breedingRepository;
        private readonly IRepository<TraceabilityInfo> _traceabilityRepository;
        private readonly IMapper _mapper;
        private readonly ILogger<QueryBreedingInfoCommandHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="breedingRepository">养殖信息仓储</param>
        /// <param name="traceabilityRepository">溯源信息仓储</param>
        /// <param name="mapper">映射器</param>
        /// <param name="logger">日志记录器</param>
        public QueryBreedingInfoCommandHandler(
            IRepository<BreedingInfo> breedingRepository,
            IRepository<TraceabilityInfo> traceabilityRepository,
            IMapper mapper,
            ILogger<QueryBreedingInfoCommandHandler> logger)
        {
            _breedingRepository = breedingRepository;
            _traceabilityRepository = traceabilityRepository;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理查询养殖信息命令
        /// </summary>
        /// <param name="request">请求命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>养殖信息</returns>
        public async Task<BreedingInfoResponseDto> Handle(QueryBreedingInfoCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("查询养殖信息，生产批次：{ProductionBatch}", request.ProductionBatch);

                // 参数验证
                if (string.IsNullOrWhiteSpace(request.ProductionBatch))
                {
                    _logger.LogWarning("生产批次不能为空");
                    throw new ApiException(ResultCode.参数错误, "生产批次不能为空");
                }

                // 首先验证溯源信息是否存在且未被删除
                var traceabilityInfo = await _traceabilityRepository.GetAll()
                    .FirstOrDefaultAsync(t => t.ProductionBatch == request.ProductionBatch && !t.IsDeleted, cancellationToken);

                if (traceabilityInfo == null)
                {
                    _logger.LogWarning("未找到对应的溯源信息，生产批次：{ProductionBatch}", request.ProductionBatch);
                    throw new ApiException(ResultCode.数据不存在, $"未找到生产批次为 {request.ProductionBatch} 的溯源信息");
                }

                // 查询养殖信息
                var breedingInfo = await _breedingRepository.GetAll()
                    .FirstOrDefaultAsync(b => b.ProductionBatch == request.ProductionBatch && !b.IsDeleted, cancellationToken);

                if (breedingInfo == null)
                {
                    _logger.LogWarning("未找到养殖信息，生产批次：{ProductionBatch}", request.ProductionBatch);
                    throw new ApiException(ResultCode.数据不存在, $"未找到生产批次为 {request.ProductionBatch} 的养殖信息");
                }

                // 映射为DTO并返回
                var breedingInfoDto = _mapper.Map<BreedingInfoResponseDto>(breedingInfo);
                _logger.LogInformation("查询养殖信息成功，生产批次：{ProductionBatch}", request.ProductionBatch);
                return breedingInfoDto;
            }
            catch (ApiException)
            {
                // 直接抛出已经包装好的业务异常
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询养殖信息失败，生产批次：{ProductionBatch}", request.ProductionBatch);
                throw new ApiException(ResultCode.服务器错误, "查询养殖信息失败，请稍后再试");
            }
        }
    }
} 